<template>
  <view class="body">
    <view class="title">
      <text class="title_text">{{ chartInfo.title }}变化情况</text>
      <view class="date-type-box">
        <text
          @tap="changeDateType('week')"
          :class="dateType === 'week' ? 'date-type action' : 'date-type'"
        >
          周
        </text>
        <text
          @tap="changeDateType('month')"
          :class="dateType === 'month' ? 'date-type action' : 'date-type'"
        >
          月
        </text>
        <text
          @tap="changeDateType('year')"
          :class="dateType === 'year' ? 'date-type action' : 'date-type'"
        >
          年
        </text>
      </view>
    </view>
    <view class="date-box">
      <view class="date-item">
        <view @tap="prevDate" class="date-item date-left">
          <uni-icons type="left" size="18" />
          {{
            dateType == 'week'
              ? parseTime(startDate, '{m}/{d}')
              : parseTime(startDate, '{y}/{m}/{d}')
          }}
        </view>
        <text style="margin: 0 8rpx">-</text>
        <view @tap="nextDate" v-if="nowDate != endDate" class="date-item date-right">
          {{
            dateType == 'week' ? parseTime(endDate, '{m}/{d}') : parseTime(endDate, '{y}/{m}/{d}')
          }}
          <uni-icons type="right" size="18" />
        </view>
        <view v-else class="date-item">
          {{
            dateType == 'week' ? parseTime(endDate, '{m}/{d}') : parseTime(endDate, '{y}/{m}/{d}')
          }}
        </view>
      </view>
      <text class="unit">
        {{ chartInfo.unit }}
      </text>
    </view>
    <view>
      <view class="echart">
        <qiun-data-charts
          :canvas2d="true"
          :canvasId="chartInfo.value"
          :type="props.chartType"
          :opts="opts"
          :chartData="chartData"
          tooltipFormat="sleepTooltip"
        />
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import qiunDataCharts from '@/module/common/qiun-data-charts/qiun-data-charts.vue'
import { ref, onMounted, watch } from 'vue'
import { bodyInfo } from './echartsInfo.api'
import { deepCopy, parseTime } from '@/utils/tools'

const xTitles = ref([])

const dateType = ref<string>('week')
const startDate = ref<string>('')
const endDate = ref<string>('')
const nowDate = ref<string>('')
const CateGories = ref<any>([])

const props = defineProps({
  empi: String,
  chartInfo: {
    type: Object,
    default: () => {}
  },
  chartType: String
})

const opts = {
  color: ['transparent', '#41A4FF'],
  dataLabel: false,
  padding: [20, 30, 10, 0],
  enableScroll: false,
  legend: {
    show: false
  },
  xAxis: {
    disableGrid: true,
    labelCount: 8,
    fontColor: '#999',
    type: 'week'
  },
  yAxis: {
    gridType: 'dash',
    dashLength: 2,
    splitNumber: props.chartInfo.splitNumber,
    gridColor: '#E5E6EB',
    data: [
      {
        axisLine: false,
        format: 'xAxisDemo2',
        max: 24,
        min: 0,
        fontColor: '#999999'
      }
    ]
  },
  extra: props.chartInfo.extra
}

const chartData = ref()
const chart_data = ref()

watch(
  () => chart_data.value,
  (n, o) => {
    if (!o || JSON.stringify(n) !== JSON.stringify(o)) {
      chartData.value = deepCopy(n)
    }
  }
)

onMounted(() => {
  CateGories.value = []
  nowDate.value = parseTime(new Date(), '{y}-{m}-{d}')
  getWeekDateRange(new Date())
})

// 默认 时间类型为周
const getWeekDateRange = (date: any) => {
  CateGories.value = []
  const week = getYearWeek(date)
  const weekArr = whichWeek(date.getFullYear())

  // 当前年月日
  const currentYear = new Date().getFullYear()
  const currentMonth = new Date().getMonth() + 1
  const currentDay = new Date().getDate()

  const wk: any = weekArr[week - 1]
  startDate.value = `${wk.year}-${wk.month}-${wk.date}`
  if (
    (currentYear === wk.last.year &&
      currentMonth === wk.last.month &&
      currentDay <= parseFloat(wk.last.date)) ||
    currentMonth < wk.last.month
  ) {
    endDate.value = `${wk.year}-${wk.month}-${currentDay < 10 ? `0${currentDay}` : currentDay}`
    const len = currentDay - Number(wk.date)
    for (let i = 0; i <= len; i++) {
      CateGories.value.push(Number(wk.date) + i)
    }
  } else {
    endDate.value = `${wk.last.year}-${wk.last.month}-${wk.last.date}`
    if (wk.month == wk.last.month) {
      const len = wk.last.date - wk.date
      for (let i = 0; i <= len; i++) {
        CateGories.value.push(Number(wk.date) + i)
      }
    } else {
      // 跨月时，逐天计算
      const startDateObj = new Date(wk.year, wk.month - 1, wk.date) // 计算开始日期
      const endDateObj = new Date(wk.last.year, wk.last.month - 1, wk.last.date) // 计算结束日期

      // 获取从开始日期到结束日期之间的所有天数
      const currentDate = startDateObj
      while (currentDate <= endDateObj) {
        CateGories.value.push(currentDate.getDate())
        currentDate.setDate(currentDate.getDate() + 1) // 日期增加一天
      }
    }
  }

  getData(props.chartInfo.value, props.chartInfo.title)
}

// 获取月类型的时间段
const getMonthDateRange = (date: any) => {
  CateGories.value = []
  // 通过传入的 date 参数获取目标年份和月份
  const targetYear = date.getFullYear()
  const targetMonth = date.getMonth() + 1 // getMonth() 从 0 开始计数

  // 获取当前日期信息
  const currentYear = new Date().getFullYear()
  const currentMonth = new Date().getMonth() + 1
  const currentDay = new Date().getDate()

  // 格式化月份，确保是两位数
  const formattedMonth = targetMonth < 10 ? `0${targetMonth}` : targetMonth

  let startDateValue
  let endDateValue

  if (targetYear === currentYear && targetMonth === currentMonth) {
    // 如果是当前月份
    startDateValue = `${targetYear}-${formattedMonth}-01`
    endDateValue = `${targetYear}-${formattedMonth}-${
      currentDay < 10 ? `0${currentDay}` : currentDay
    }`
    const len = currentDay - 1
    for (let i = 0; i <= len; i++) {
      CateGories.value.push(1 + i)
    }
  } else {
    // 如果是过去的月份，获取该月的最后一天
    const lastDay = new Date(targetYear, targetMonth, 0).getDate()
    startDateValue = `${targetYear}-${formattedMonth}-01`
    endDateValue = `${targetYear}-${formattedMonth}-${lastDay}`
    const len = lastDay - 1
    for (let i = 0; i <= len; i++) {
      CateGories.value.push(1 + i)
    }
  }
  startDate.value = startDateValue
  endDate.value = endDateValue

  getData(props.chartInfo.value, props.chartInfo.title)
}

// 获取年的时间段
const getYearDateRange = (date: any) => {
  CateGories.value = []
  // 当前年份
  const currentYear = new Date().getFullYear()
  const currentMonth = new Date().getMonth() + 1
  const currentDay = new Date().getDate()

  const targetYear = date.getFullYear()

  startDate.value = `${targetYear}-01-01`
  if (targetYear === currentYear) {
    endDate.value = `${targetYear}-${currentMonth < 10 ? `0${currentMonth}` : currentMonth}-${
      currentDay < 10 ? `0${currentDay}` : currentDay
    }`
    const len = currentMonth - 1
    for (let i = 0; i <= len; i++) {
      CateGories.value.push(1 + i)
    }
  } else {
    endDate.value = `${targetYear}-12-31`
    const len = 12 - 1
    for (let i = 0; i <= len; i++) {
      CateGories.value.push(1 + i)
    }
  }

  getData(props.chartInfo.value, props.chartInfo.title)
}
const getData = (item: string, name: string) => {
  xTitles.value = []
  const params = {
    empi: props.empi, // props.empi
    paramKey: item,
    timeType: dateType.value.toUpperCase(),
    startTime: parseTime(startDate.value, '{y}-{m}-{d} 00:00:00'),
    endTime: parseTime(endDate.value, '{y}-{m}-{d} 23:59:59')
  }
  bodyInfo(params).then((res: any) => {
    const categories: any = []
    const series = []
    const data: any = []
    const weekUpDta: any = []
    if (res.data && res.data.length > 0) {
      res.data.map((v) => {
        if (dateType.value == 'year') {
          if (v.sleepDuration) {
            const weekupTimes =
              parseFloat(v.weekupTime.split(':')[0]) + parseFloat(v.weekupTime.split(':')[1]) / 60
            parseFloat(v.weekupTime.split(':')[2]) / 3600
            const sleepTimes =
              parseFloat(v.sleepTime.split(':')[0]) + parseFloat(v.sleepTime.split(':')[1]) / 60
            parseFloat(v.sleepTime.split(':')[2]) / 3600

            const sleepDuration = parseFloat(v.sleepDuration)
            data.push(sleepDuration)
            weekUpDta.push(18 - weekupTimes)
            categories.push(v.dateName)
          }
        } else {
          const jsonData = JSON.parse(v.param_value)
          const weekupTimes =
            parseFloat(parseTime(jsonData.weekupTime, '{h}')) +
            parseFloat(parseTime(jsonData.weekupTime, '{i}')) / 60
          const sleepTimes =
            parseFloat(parseTime(jsonData.sleepTime, '{h}')) +
            parseFloat(parseTime(jsonData.sleepTime, '{i}')) / 60

          const sleepDuration = parseFloat(jsonData.sleepDuration)
          data.unshift(sleepDuration)
          weekUpDta.unshift(18 - weekupTimes)
          categories.unshift(parseTime(v.dateName, '{d}'))
        }
      })
    }
    if (res.data.length == 0) {
      const arr = new Array(CateGories.value.length).fill(null)
      series.push({
        connectNulls: true,
        name: name,
        data: arr
      })
    } else {
      series.push(
        {
          name: '醒来时间',
          data: weekUpDta,
          format: 'sleepTime'
        },
        {
          name: '睡眠时长',
          data: data,
          format: 'sleepDuration'
        }
      )
      // 为年的时候判断数组中weekupTime是否存在
      let hasWeek = false
      if (dateType.value == 'year') {
        for (let i = 0; i < res.data.length; i++) {
          if (res.data[i].weekupTime) {
            hasWeek = true
          }
        }
        if (!hasWeek) {
          CateGories.value.map((v: any) => {
            categories.push(v)
          })
          const arr = new Array(CateGories.value.length).fill(null)
          series.splice(0, 2)
          series.push({
            connectNulls: true,
            name: name,
            data: arr
          })
        }
      }
    }

    chart_data.value = {
      categories: res.data.length == 0 ? CateGories.value : categories,
      series: series
    }
  })
}

// 类型切换
const changeDateType = (type: string) => {
  dateType.value = type
  opts.xAxis.type = type
  const date = new Date()
  switch (type) {
    case 'week':
      getWeekDateRange(date)
      break
    case 'month':
      getMonthDateRange(date)
      break
    case 'year':
      getYearDateRange(date)
      break
    default:
      break
  }
}

const whichWeek = (year: any) => {
  var d = new Date(year, 0, 1)
  while (d.getDay() != 1) {
    d.setDate(d.getDate() + 1)
  }
  const arr = []
  const longnum = d.setDate(d.getDate())
  if (longnum > +new Date(year, 0, 1)) {
    const obj = yearDay(+new Date(year, 0, 1) / 1000)
    obj.last = yearDay(longnum / 1000 - 86400)
    arr.push(obj)
  }
  const oneitem = yearDay(longnum / 1000)
  oneitem.last = yearDay(longnum / 1000 + 86400 * 6)
  arr.push(oneitem)
  let lastStr = 0
  for (var i = 0; i < 51; i++) {
    const long = d.setDate(d.getDate() + 7)
    const obj = yearDay(long / 1000)
    obj.last = yearDay(long / 1000 + 86400 * 6)
    lastStr = long + 86400000 * 6
    arr.push(obj)
  }
  if (lastStr < +new Date(year + 1, 0, 1)) {
    const obj = yearDay(lastStr / 1000 + 86400)
    obj.last = yearDay(+new Date(year + 1, 0, 1) / 1000 - 86400)
    arr.push(obj)
  } else {
    arr[arr.length - 1].last = yearDay(+new Date(year + 1, 0, 1) / 1000 - 86400)
  }
  return arr
}

const yearDay = (long: any) => {
  var time = new Date(long * 1000)
  var year = time.getFullYear()
  var month = time.getMonth() + 1 < 10 ? '0' + (time.getMonth() + 1) : time.getMonth() + 1
  var date = time.getDate() < 10 ? '0' + time.getDate() : time.getDate()
  var yearday = { year, month, date }
  return yearday
}

const getYearWeek = (endDate: any) => {
  //本年的第一天
  const beginDate = new Date(endDate.getFullYear(), 0, 1)
  //星期从0-6,0代表星期天，6代表星期六
  let endWeek = endDate.getDay()
  if (endWeek == 0) {
    endWeek = 7
  }
  let beginWeek = beginDate.getDay()
  if (beginWeek == 0) {
    beginWeek = 7
  }
  //计算两个日期的天数差
  const millisDiff = endDate.getTime() - beginDate.getTime()
  const dayDiff = Math.floor(
    (millisDiff + (beginWeek - endWeek) * (24 * 60 * 60 * 1000)) / 86400000
  )
  return Math.ceil(dayDiff / 7) + 1
}

const prevDate = () => {
  if (dateType.value == 'week') {
    const date = new Date(new Date(startDate.value).getTime() - 7 * 24 * 60 * 60 * 1000)
    getWeekDateRange(date)
  } else if (dateType.value == 'month') {
    // 创建一个新的日期对象用于计算上个月的日期
    const lastMonthDate = new Date(startDate.value)
    // 设置上个月
    lastMonthDate.setMonth(lastMonthDate.getMonth() - 1)
    getMonthDateRange(lastMonthDate)
  } else {
    // 创建一个新的日期对象用于计算去年的日期
    const lastYearDate = new Date(startDate.value)
    // 设置去年
    lastYearDate.setFullYear(lastYearDate.getFullYear() - 1)
    getYearDateRange(lastYearDate)
  }
}
const nextDate = () => {
  if (dateType.value == 'week') {
    const date = new Date(new Date(startDate.value).getTime() + 7 * 24 * 60 * 60 * 1000)
    getWeekDateRange(date)
  } else if (dateType.value == 'month') {
    // 创建一个新的日期对象用于计算上个月的日期
    const lastMonthDate = new Date(startDate.value)
    // 设置上个月
    lastMonthDate.setMonth(lastMonthDate.getMonth() + 1)
    getMonthDateRange(lastMonthDate)
  } else {
    // 创建一个新的日期对象用于计算去年的日期
    const lastYearDate = new Date(startDate.value)
    // 设置去年
    lastYearDate.setFullYear(lastYearDate.getFullYear() + 1)
    getYearDateRange(lastYearDate)
  }
}
</script>

<style lang="scss" scoped>
.body {
  padding: 32rpx;
  margin-bottom: 32rpx;
  background: #fff;
  border-radius: 12rpx;

  .echart {
    width: 100%;
    height: 360rpx !important;
  }

  .title {
    display: flex;
    gap: 16rpx;
    align-items: center;
    justify-content: space-between;
    height: 68rpx;
    padding-bottom: 10rpx;
    border-bottom: 1rpx solid #e5e6eb;

    .img_logo {
      width: 32rpx;
      height: 32rpx;
      transform: translateY(6rpx);
    }

    .title_text {
      font-size: 32rpx;
      font-weight: 600;
      color: #222;
    }
  }

  .unit {
    font-size: 24rpx;
    font-weight: 400;
    color: #666;
  }

  .xtitle {
    display: flex;
    flex-wrap: nowrap;
    justify-content: space-around;
    padding-left: 50rpx;

    .xtext {
      font-size: 24rpx;
      font-weight: 400;
      color: #666;
    }
  }
}

.date-type-box {
  display: flex;
  width: 144rpx;
  height: 48rpx;
  border: 1rpx solid #00d1b6;
  border-radius: 34rpx;
  transform: rotateZ(360deg);
}

.date-type {
  display: inline-block;
  width: 48rpx;
  height: 44rpx;
  font-size: 24rpx;
  font-weight: 400;
  line-height: 44rpx;
  color: #666;
  text-align: center;
}

.date-type.action {
  font-weight: 500;
  color: #fff;
  background-color: #00d1b6;
  border-radius: 40rpx;
}

.date-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16rpx;
  font-size: 22rpx;
}

.date-item {
  display: flex;
  align-items: center;
  font-size: 26rpx;
}

.date-left {
  padding-left: 24rpx;
  margin-left: -24rpx;
}

.date-right {
  padding-right: 24rpx;
}
</style>
